<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2015/7/31
 * Time: 11:04
 */

namespace App\Utils;


use Illuminate\Support\Str;

class FileUtils
{

    public static function get_file_content($filename)
    {
        if (!file_exists($filename) || is_dir($filename)) {
            return "";
        }

        $handle = fopen($filename, "r");
        $content = fread($handle, filesize($filename));
        fclose($handle);
        unset($handle);
        return $content;
    }

    public static function copy_file($srcFile, $distFile)
    {
        try {
            $handle = fopen($srcFile, "r");
            $content = fread($handle, filesize($srcFile));
            fclose($handle);
            unset($handle);
            $handle = fopen($distFile, "w+");
            fwrite($handle, $content);
            fclose($handle);
        } catch (\Exception $e) {
            return false;
        }
        return true;
    }

    public static function replace_file_content($filename, $matrix)
    {
        $content = self::get_file_content($filename);
        foreach ($matrix as $key => $value) {
            $content = str_replace($key, $value, $content);
        }
        $handle = fopen($filename, "w");
        fwrite($handle, $content);
        fclose($handle);
        return true;
    }

    public static function write_csv($matrix, $file, $title = array(), $info = "", $sum = "", $label = "", $encode = "gbk", $writeBOM = true)
    {
        $str = $info;
        if (count($matrix) > 0) {
            $columns = array_keys($matrix[0]);
            for ($i = 0; $i < count($columns); $i++) {
                $mc = $columns[$i];
                if ($title != null && is_array($title) && array_key_exists($mc, $title)) {
                    $mc = $title[$mc];
                }
                $str .= ($i > 0) ? "," : "";
                $str .= $mc;
            }
        }
        for ($i = 0; $i < count($matrix); $i++) {
            $index = 0;
            $str .= "\r\n";
            while (list($key, $value) = each($matrix[$i])) {
                $str .= ($index > 0) ? "," : "";
                if ($label == $key) {
                    $str .= "\"" . str_replace('"', '""', label("message.message_type_" . $value)) . "\"";
                } else {
                    $str .= "\"" . str_replace('"', '""', $value) . "\"";
                }
                $index++;
            }
        }
        $str .= $sum;
        //$str = iconv("utf-8","gb18030//IGNORE",$str);
        self::rewrite_file($file, $str, $encode, $writeBOM);
        return true;
    }


    public static function download_file($filename)
    {
        $name = get_base_name($filename);
        $filename = to_os_encoding($filename);

        if (file_exists($filename)) {
            send_file($filename, $name);
        } else {
            // do_alert("file not exists");
        }
    }

    public static function send_file($file, $name)
    {
        global $_SERVER;

        if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
            $name = iconv("utf-8", "gb2312", $name);
        }
        $type = self::get_file_type($file);
        $type = strtolower($type);

        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Content-Type: application/force-download");
        if ($type == "apk") {
            header("Content-Type: application/vnd.android.package-archive");
        } else {
            header("Content-Type: application/octet-stream");
            header("Content-Type: application/download");
        }

        header("Content-Disposition: attachment; filename=" . ($name) . "");
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: " . filesize($file));

        ob_clean();
        flush();
        readfile($file);
        // exit();
    }

    public static function check_file_newest($targetFile, $compareFile)
    {
        if (!file_exists($targetFile)) {
            return false;
        } else {
            $t1 = filemtime($targetFile);
            $t2 = filemtime($compareFile);
            if ($t1 <= $t2) {
                return false;
            }
        }
        return true;
    }


    public static function rewrite_file($targetFile, $content, $encode = "gb18030", $writeBom = true)
    {
        $handle = fopen($targetFile, 'w+');
        $bianma = CharsetUtils::to_utf8_name(CharsetUtils::get_php_encoding());
        $encode = CharsetUtils::to_utf8_name($encode);

        if ($encode == "utf-8") {
            if ($writeBom) {
                $content = "\xEF\xBB\xBF" . $content;
            }
        }

        if ($encode != $bianma) {
            $content = iconv($bianma, $encode . "//IGNORE", $content);
        }

        fwrite($handle, $content);
        fclose($handle);
    }

    public static function get_real_folder($relativePath)
    {
        return str_replace("\\", "/", realpath($relativePath)) . "/";
    }

    public static function get_real_path($relativePath)
    {
        return realpath($relativePath);
    }

    public static function get_file_type($name)
    {
        $matrix = explode(".", $name);
        if (count($matrix) > 1) {
            return strtolower($matrix[count($matrix) - 1]);
        }
        return "";
    }

    public static function list_folder($folder)
    {
        $matrix = array();
        if (($d = dir($folder)) != "") {
            while ($file = $d->read()) {
                if (substr($file, 0, 1) == '.') {
                    continue;
                }
                $path = $folder . "/" . $file;
                array_push($matrix, $path);
            }
        }
        return $matrix;
    }

    public static function find_folders($folder)
    {
        $matrix = array();
        if (($d = dir($folder)) != "") {
            while ($file = $d->read()) {
                if (substr($file, 0, 1) == '.') {
                    continue;
                }
                $path = rtrim($folder, '/') . '/' . $file;
                if (is_dir($path)) {
                    array_push($matrix, $file);
                }
            }
        }
        return $matrix;
    }

    public static function find_files($folder, $types = array(), $include_sub_folder = true)
    {
        $files = array();
        $folders = array();
        if (($d = dir($folder)) != "") {
            while ($file = $d->read()) {
                if (substr($file, 0, 1) == '.') {
                    continue;
                }
                if (is_dir("$folder/$file")) {
                    if ($include_sub_folder) {
                        // print_html($folder."$file/");
                        array_push($folders, $folder . "$file/");
                    }
                    continue;
                }
                $type = self::get_file_type($file);
                if (empty($types) || in_array($type, $types)) {
                    // print_html($folder.$file);
                    array_push($files, $folder . $file);
                }
            }
        }
        if ($include_sub_folder) {
            for ($i = 0; $i < count($folders); $i++) {
                $list = self::find_files($folders[$i], $types, $include_sub_folder);
                $files = array_merge($files, $list);
            }
        }
        // print_r($files);
        return $files;
    }

    public static function create_folder($path, $Permission = 0755)
    {
        $path = FileUtils::to_linux_path($path);
        $matrix = explode("/", $path);
        $folder = $matrix[0];
        for ($i = 1; $i < count($matrix); $i++) {
            $folder = $folder . "/" . $matrix[$i] . "/";
            if (file_exists($folder)) {
                continue;
            }
            self::mkdirs($folder, $Permission);
        }
        return true;
    }

    public static function delete_dir($dir)
    {
        $dh = opendir($dir);
        while ($file = readdir($dh)) {
            if ($file != "." && $file != "..") {
                $fullpath = $dir . "/" . $file;
                //echo $fullpath."<br/>";
                if (!is_dir($fullpath)) {
                    unlink($fullpath);
                } else {
                    delete_dir($fullpath);
                }
            }
        }
        closedir($dh);
        if (rmdir($dir)) {
            return true;
        } else {
            return false;
        }
    }

    public static function lsr($dir)
    {
        $a = array();
        if (($d = dir($dir)) != "") {
            while ($file = $d->read()) {
                if ($file == '.' || $file == '..') {
                    continue;
                }
                if (is_dir("$dir/$file")) {
                    $a[$file] = lsr("$dir/$file");
                } else {
                    $a[] = $file;
                }
            }
        }
        $d->close();
        return $a;
    }

    public static function get_file($url, $folder = "./")
    {
        set_time_limit(1 * 60 * 60);         //设置超时时间
        $destination_folder = $folder . '/'; // 文件下载保存目录，默认为当前文件目录
        if (!is_dir($destination_folder)) { // 判断目录是否存在
            self::mkdirs($destination_folder); // 如果没有就建立目录
        }
        $newfname = $destination_folder . absolutly_basename($url); // 取得文件的名称
        $file = fopen($url, "rb"); // 远程下载文件，二进制模式
        $newf = 0;
        if ($file) { // 如果下载成功
            $newf = fopen($newfname, "wb"); // 远在文件文件
            if ($newf) { // 如果文件保存成功
                while (!feof($file)) { // 判断附件写入是否完整
                    fwrite($newf, fread($file, 1024 * 8), 1024 * 8); // 没有写完就继续
                }
            }
        }
        if ($file) {
            fclose($file); // 关闭远程文件
        }
        if ($newf) {
            fclose($newf); // 关闭本地文件
        }
        return true;
    }

    public static function mkdirs($path, $mode = "0755", $times = 0)
    {
        if (file_exists($path)) {
            return true;
        }
        if (!is_dir($path)) { // 判断目录是否存在
            $times++;
            if ($times > 12) {
                return false;
            }
            self::mkdirs(dirname($path), $mode, $times); // 循环建立目录
            @mkdir($path, $mode); // 建立目录
            @chmod($path, $mode);
        }
        return true;
    }

    public static function get_file_path($file)
    {
        $baseName = self::get_base_name($file);
        return str_replace($baseName, "", $file);
    }

    public static function get_base_name($file)
    {
        $file = str_replace("\\", "/", $file);
        $temp = explode("/", $file);
        $name = $temp[count($temp) - 1];
        $temp = explode("?", $name);
        return $temp[0];
    }

    public static function unzip_with_encoding($zipFile, $sourceEncoding = "GBK", $unsafeFileTypes = array())
    {
        $a = zip_open($zipFile);
        $result = "";
        $i = 0;
        while ($e = zip_read($a)) {
            $fz = zip_entry_filesize($e);
            $ff = zip_entry_name($e);
            $ff = str_replace(' ', '_', $ff);

            $ff = self::get_file_path($zipFile) . $ff;

            if ($sourceEncoding != get_os_encoding()) {
                $ff = iconv($sourceEncoding, get_os_encoding(), $ff);
            }
            if (!$fz) {//dir
                if (file_exists($ff)) {
                    //$num = substr_count($ff,"/");
                    if ($i > 0) {
                        $result .= ",";
                    }
                    $result .= string_index($ff, "/", -2, 2);
                    $i++;
                    continue;
                } else {
                    self::mkdirs($ff, 0777);
                    continue;
                }
            }
            $type = self::get_file_type($ff);

            if (in_array($type, $unsafeFileTypes)) {
                $result = "nonsupport";
                continue;
            }
            if (file_exists($ff)) {
                //$num = substr_count($ff,"/");
                if ($i > 0) {
                    $result .= ",";
                }
                $result .= string_index($ff, "/", -1, 1);
                $i++;
                continue;
            }

            if (!zip_entry_open($a, $e, 0777)) {
                $result = "fail";
                continue;
            }
            if (!file_put_contents($ff, zip_entry_read($e, $fz))) {
                $result = "fail";
                continue;
            }
            zip_entry_close($e);

        }
        zip_close($a);
        return $result;
    }

    public static function one_file_of_unzip($zipFile, $sourceEncoding = "GBK", $unsafeFileTypes = array())
    {
        $a = zip_open($zipFile);
        $result = "";
        $e = zip_read($a);

        $fz = zip_entry_filesize($e);
        $ff = zip_entry_name($e);

        $ff = self::get_file_path($zipFile) . $ff;

        if ($sourceEncoding != get_os_encoding()) {
            $ff = iconv($sourceEncoding, get_os_encoding(), $ff);
        }

        $type = self::get_file_type($ff);
        if (in_array($type, $unsafeFileTypes)) {
            $result = "nonsupport";
        }
        $newff = $ff;
        if (file_exists($ff)) {
            $newff .= date('Ymdhis');
        }

        if (!zip_entry_open($a, $e, 0777)) {
            $result = "fail";
        }
        if (!file_put_contents($newff, zip_entry_read($e, $fz))) {
            $result = "fail";
        }
        $result = $result == '' ? $newff : $result;
        zip_entry_close($e);
        zip_close($a);

        return $result;

    }

    /**
     * 获取当前文件夹的大小（不是从库表获取的） 传参是文件夹路径
     */
    public static function get_dir_size($dir)
    {
        $handle = opendir($dir);
        $sizeResult = 0;
        while (false !== ($FolderOrFile = readdir($handle))) {
            if ($FolderOrFile != '.' && $FolderOrFile != '..') {
                if (is_dir($dir . '/' . $FolderOrFile)) {
                    $sizeResult += self::get_dir_size($dir . '/' . $FolderOrFile);
                } else {
                    $sizeResult += filesize("$dir/$FolderOrFile");
                }
            }
        }
        closedir($handle);
        return $sizeResult;
    }

    public static function to_linux_path($path)
    {
        return str_replace("\\", "/", $path);
    }
}